02 Binding de eventos

Próxima Atividade
  • Sugerir melhoria
Carregando vídeo

Transcrição

Vamos melhorar a experiência do usuário em nossa aplicação. Atualmente temos 12 imagens em exibição na página; e se futuramente tivermos 100, 200? Seria interessante darmos ao usuário a opção de filtrar, por exemplo. Sabemos que cada objeto utilizado para a construção destes componentes possui a propriedade description, a ideia é colocarmos um campo de filtro no qual digitaremos parte do texto que está nesta descrição, e todas as imagens que a possuírem serão exibidas, enquanto as demais serão omitidas da página.

Em photo-list.component.html, que envolve o componente que traz os dados e os disponibiliza para photos.component.html, componente que os renderiza usando o grid do Bootstrap, acrescentaremos o seguinte trecho:

<div class="text-center mt-3 mb-3">
    <form>
        <input
            class="rounded"
            type="search"
            placeholder="search..."
            autofocus>
    </form>
</div>

Com isso, o <input> ficará centralizado na <div> e terá bordas arredondadas (rounded), será do tipo search, e possuirá foco assim que a página for carregada. E as classes mt-3 e mb-3 implicam nas margens de topo e de baixo, ambas com valor 3, valor arbitrário do Bootstrap. Salvaremos e voltaremos ao navegador, com o campo de busca implementado, porém ainda não pronto para uso.

De que maneira capturaremos o dado digitado neste campo de busca? E depois, como será realizada a filtragem deste valor? Em algum momento sabemos que este valor deverá cair em uma propriedade de PhotoListComponent, portanto criaremos em photo-list.component.ts a propriedade filter, do tipo string, que começa inicializada com uma string em branco. À medida em que formos digitando no input do navegador, o valor será atribuído a esta propriedade.

Qual é o evento do JavaScript podemos trabalhar para lidar com isso? Uma das opções é o keyup, disparado à medida em que digitamos. Para entendermos melhor, vamos supor que trabalhamos com JavaScript puro, e sem arrow function para facilitar a legibilidade:

h1.addEventListener('keyup', function(event) {
    alert('oi')
});

Com este código, a cada valor digitado pelo usuário no h1, acessado em DOM, será exibido um alerta. Por meio do event conseguimos acessar o valor de alert('oi'), sendo possível utilizarmos event.target.value para saber o que foi digitado.

Voltando ao código que estávamos escrevendo, indicaremos em keyup que filter receberá $event.target.value, o que se assemelha ao JavaScript puro que usamos de exemplo, com a diferença de que, no lugar de event, usamos $event do Angular, tratado e modificado.

<form>
    <input
        class="rounded"
        type="search"
        placeholder="search..."
        autofocus
        keyup="filter = $event.target.value"
    >
</form>

Então, a cada valor que for digitado no campo de busca, o valor do input será acessado usando-se a propriedade filter. No entanto, nada acontecerá, pois se mantermos o código assim, o Angular entenderá que estamos usando a string filter = $event.target.value dentro do evento keyup.

Já aprendemos que existe um tal de Data binding, então podemos supor que usar [keyup]="filter = $event.target.value" resolverá nosso problema, o que também não é o caso, já que este Data binding buscará a expressão entre aspas no componente, e este atributo não existe.

Para resolvermos isso, precisaremos realizar um Data binding que é um Event binding. Isto, no Angular, é feito colocando-se o nome do evento entre parênteses — (keyup)="filter = $event.target.value". Ou seja, para o evento keyup, a expressão "filter = $event.target.value" será avaliada.

Porém, esta associação de eventos se difere ao uso de colchetes, como em um Data binding regular, cujo dado vem da fonte de dados (componente) para o template, nunca o caminho inverso. Já quando utilizamos os parênteses, fazemos exatamente o oposto, isto é, o evento é disparado, indo da view do template para o componente.

É importante entendermos que estes bindings são unidirecionais, cada qual percorrendo um caminho diferente. Vamos salvar o projeto, abrir a página no navegador, consultar o console, em que não teremos nenhum erro. E para nos assegurarmos de que o campo de busca captura o termo digitado, incluiremos uma Expression language para a propriedade filter.

O código de photo-list.component.html ficará assim:

<div class="text-center mt-3 mb-3">
    <form>
        <input
            class="rounded"
            type="search"
            placeholder="search..."
            autofocus
            (keyup)="filter = $event.target.value"
            >
    </form>
</div>
{{ filter }}
<ap-photos [photos]="photos"></ap-photos>

Ao salvarmos tudo, voltarmos ao navegador e digitarmos "calopsita" (ou qualquer outro termo), à medida em que vamos digitando, a palavra vai se formando no layout antes da exibição das imagens. Deste modo temos certeza de que tudo está sendo adicionado por meio do binding de evento, e modificado no filter, atualizado conforme nossa digitação.

Quando abrimos a aplicação, um Data binding unidirecional ocorre, de filter para o template, e nada é exibido. Para que isso fique claro, podemos atribuir um valor inicial (flavio) temporariamente em filter: string = 'flavio' de photo-list.component.ts, e reabrir a página, e teremos "flavio" sendo exibido antes das imagens.

Agora, precisamos usar o valor que está no filter para de fato filtrarmos a lista. Faremos isto a seguir!

Tirar dúvida Próxima Atividade
ícone Angular parte 1: Fundamentos

Angular parte 1: Fundamentos

100%
Aula06 de 07

Melhorando a experiência do usuário

Atividades 2 de 11

  • 01 Projeto da aula anterior
  • 02 Binding de eventos 11min
  • 03 Pipe e implementação 14min
  • 04 Criando nosso próprio pipe
  • 05 Resolvers 12min
  • 06 Implementando Resolvers
  • 07 RxJS e seu Subject 12min
  • 08 Padrão debounce com RxJS
  • 09 Paginação de dados 07min
  • 10 LoadButton 16min
  • 11 Consolidando seu conhecimento

Aulas

Outros Links

Fórum Trocar Curso
Gravatar de Marcos Katsumi Kay

Marcos Katsumi Kay 34.4k xp

Logo da Alura